﻿#include "iot.h"

#include <QJsonArray>

iot::iot(QObject *parent)
    : QObject{parent}
{
    networkManager = new QNetworkAccessManager();
}

/**
 * @brief 获取华为云IAM Token
 * @param username IAM用户名（华为云账户名）
 * @param password IAM用户密码
 * @param domainName 账户所属域（默认为华为云账号名）
 * @return 成功返回Token，失败返回""
 */
QString iot::getAccessToken()
{
    QJsonObject authBody = {
        {"auth", QJsonObject{
            {"identity", QJsonObject{
                {"methods", QJsonArray{"password"}},
                {"password", QJsonObject{
                    {"user", QJsonObject{
                        {"name", IAMNAME},
                        {"password", IAMSECRET},
                        {"domain", QJsonObject{
                            {"name", DOMAIN}
                        }}
                    }}
                }}
            }},
            {"scope", QJsonObject{
                {"project", QJsonObject{
                    {"name", REGION},
                }}
            }}
        }}
    };
    QNetworkRequest request(QUrl(IAMURL));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json;charset=utf-8");

    QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration();
    sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
    request.setSslConfiguration(sslConfig);

    QNetworkReply *reply = networkManager->post(request, QJsonDocument(authBody).toJson());
    QEventLoop loop;
    connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    if (reply->error() != QNetworkReply::NoError) {
        return "";
    }

    // 从响应头提取Token
    QString token = reply->rawHeader("X-Subject-Token");
    return token;
}


/**
 * @brief 查询设备在线状态
 * @param token 通过getAccessToken获取的鉴权Token
 * @return 设备状态（"ONLINE"/"OFFLINE"）,若执行失败，返回"";
 */
bool iot::getDeviceStatus(const QString &token) {

    //c14639db19.st1.iotda-app.cn-north-4.myhuaweicloud.com  -->应用端https接入地址
    QString url = QString("https://c14639db19.st1.iotda-app.cn-north-4.myhuaweicloud.com/v5/iot/%1/devices/%2")
                      .arg(PROJECTID).arg(DEVICEID);
    QNetworkRequest request((QUrl(url)));
    request.setRawHeader("X-Auth-Token", token.toUtf8());

    QNetworkReply *reply = networkManager->get(request);
    QEventLoop loop;
    connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();
    if (reply->error() != QNetworkReply::NoError) {
        return "";
    }
    QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
    QString isLink =  doc.object().value("status").toString();
    if(isLink == "OFFLINE"){
        return false;
    }
    else return true;

}


/**
 * @brief 获取设备影子数据
 * @param token 鉴权Token
 * @return 包含设备属性（温度、湿度等）的JSON对象,若执行失败，返回空q
 */
QJsonObject iot::getDeviceShadowData(const QString &token)
{
    QString url = QString("https://c14639db19.st1.iotda-app.cn-north-4.myhuaweicloud.com/v5/iot/%1/devices/%2/shadow")
    .arg(PROJECTID).arg(DEVICEID);

    QNetworkRequest request((QUrl(url)));
    request.setRawHeader("X-Auth-Token", token.toUtf8());
    QNetworkReply *reply = networkManager->get(request);
    QEventLoop loop;
    connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();
    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "status获取失败：" << reply->errorString();
        return QJsonObject();
    }
    QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
    QJsonObject rootObj = doc.object();
    QJsonArray shadowArray = rootObj["shadow"].toArray();
    QJsonObject firstShadow = shadowArray[0].toObject();
    QJsonObject reported = firstShadow["reported"].toObject();
    return reported["properties"].toObject();
}


/**
 * @brief iot::sendCommandToDevice
 * @param token
 * @param stl 模式数组
 * @return 未接收到下位机的反馈则返回空，否则返回JSON里的result值
 */
QString iot::sendCommandToDevice(const QString &token,QStringList&stl)
{
    QString url = QString("https://c14639db19.st1.iotda-app.cn-north-4.myhuaweicloud.com/v5/iot/%1/devices/%2/commands")
    .arg(PROJECTID).arg(DEVICEID);
    QNetworkRequest request((QUrl(url)));

    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json;charset=utf-8");
    request.setRawHeader("X-Auth-Token", token.toUtf8());
    QJsonObject command = {
        {"service_id", "slave_computer"},
        {"command_name", "cmd"},
        {"paras", QJsonObject{{"control", QJsonArray::fromStringList(stl)}}}
    };
    QNetworkAccessManager manager;
    qDebug()<<"开始发送指令";
    QNetworkReply* reply = manager.post(request, QJsonDocument(command).toJson());

    QEventLoop loop;
    connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();
    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "获取反馈失败：" << reply->errorString();
        return "";
    }
    else{
        QJsonDocument root = QJsonDocument::fromJson(reply->readAll());
        QJsonObject response= root.object().value("response").toObject();
        QJsonObject paras = response.value("paras").toObject();
        qDebug()<<"result: "<<paras.value("result").toString();
        return paras.value("result").toString();
    }
}
